import { Toast } from "@/hooks/Providers";
import { handleLoginInfo } from "@/hooks/useLoginInfo";
import { useRefNow } from "@/hooks/useRefNow";
import { LoadingOutlined } from "@ant-design/icons";
import { SSO } from "@nsb/user-center-sso-plugin";
import { Button, Empty, Flex, Modal, ModalProps, Typography } from "antd";
import { t } from "i18next";
import { ReactNode, useEffect, useRef, useState } from "react";
import { Show } from "../Display";
const modal_style: React.CSSProperties = {
  // top: '30%',
  // transform: 'translateY(-30%)',
  // transition: 'all 200ms',
}
export interface ILoginModalProps extends ModalProps {
  on_resolve?(): void;
  on_pending?(pending: boolean): void;
}
export function LoginModal(props: ILoginModalProps) {
  const { on_resolve, on_pending, open, ..._p } = props;
  const [[w, h], set_size] = useState<[number, number]>([380, 350]);
  return (
    <Modal
      footer={null}
      open={open}
      width={w}
      styles={{ content: { padding: 0, overflow: 'hidden' }, body: { height: h }, }}
      style={modal_style}
      closeIcon={null}
      forceRender
      destroyOnClose
      {..._p}>
      <LoginView
        open={open}
        on_size_change={(w, h) => set_size([w, h])}
        on_resolve={on_resolve}
        on_pending={on_pending} />
    </Modal>
  )
}
interface ILoginViewProps {
  open?: boolean;
  on_size_change(width: number, height: number): void,
  on_resolve?(): void;
  on_pending?(pending: boolean): void;
}
function LoginView(props: ILoginViewProps) {
  const { on_size_change, on_resolve, on_pending, open } = props
  const [pending, set_pending] = useState(true);
  const [retry_times, set_retry_times] = useState(0);
  useEffect(()=>{
    open && set_retry_times(v=>++v)
  },[open])
  const [error_msg, set_error_msg] = useState<ReactNode>();
  const ref_is_ready = useRef(false);
  const ref_set_error_msg = useRefNow(set_error_msg)
  const ref_on_resolve = useRefNow(on_resolve)
  const ref_on_pending = useRefNow((v: boolean) => {
    on_pending?.(v);
    set_pending(v);
  })
  const ref_iframe = useRef<HTMLIFrameElement>(null)
  const [toast] = Toast.use()
  useEffect(() => {
    const iframe = ref_iframe.current;
    if (!iframe)
      return;
    const sso = new SSO({
      iframe,
      path: '/sso_view',
      title: t("app.name"),
      origin: __USER_CENTER_SSO_ORIGIN__,
      domainId: __SSO_DOMAIN_ID__, 
      device: "goltach_windows",
    })
    sso.on('size_changed', ({ width, height }) => on_size_change(width, height))
    sso.on('resolve', handleLoginInfo)
    sso.on('resolve', () => ref_on_resolve.current?.())
    sso.on('reject', (reason) => {
      if (reason === 'permission_denied')
        toast.error(t("common.main_permission_denied"))
    })
    ref_is_ready.current = false;
    ref_on_pending.current(true)
    let timer: ReturnType<typeof setTimeout> | null = null;
    const on_iframe_load = () => {
      if (ref_is_ready.current) return;
      timer = setTimeout(() => {
        if (ref_is_ready.current) return;
        stop_listen_ready();
        ref_set_error_msg.current("访问用户中心超时")
        ref_on_pending.current(false)
      }, 5000)
    }
    iframe.addEventListener('load', on_iframe_load, { once: true })
    const stop_listen_ready = sso.on('ready', () => {
      ref_is_ready.current = true;
      iframe.removeEventListener('load', on_iframe_load)
      sso.tunnel.fetch('login_info', true).then((info) => {
        handleLoginInfo(info)
      }).catch((msg) => {
        console.log("[SSO] login_info, failed:", msg)
      }).finally(() => {
        ref_on_pending.current(false)
      });
    })
    return () => {
      iframe.removeEventListener('load', on_iframe_load)
      if (timer) {
        clearTimeout(timer)
        timer = null
      }
      sso.destroy()
    }
  }, [ref_iframe, retry_times])

  const is_success = (!pending && !error_msg)// || document.body.classList.contains('dev')
  const is_failed = !pending && !!error_msg
  return <>
    <iframe
      style={{ ...inner_style, opacity: is_success ? 1 : 0 }}
      ref={ref_iframe}
      title='user-center-sso' />
    {/* sandbox='allow-scripts allow-top-navigation allow-same-origin' /> */}
    <Show yes={is_failed}>
      <Empty
        style={inner_style}
        description={
          <Flex gap={10} vertical align='center' justify='center'>
            {error_msg}
            <Button type='primary' size='small' onClick={() => set_retry_times(v => ++v)}>重试</Button>
          </Flex>
        } />
    </Show>
    <Show yes={pending}>
      <Flex gap={10} style={inner_style} align='center' justify='center'>
        <LoadingOutlined />
        <Typography.Text type='secondary'>
          正在访问用户中心...
        </Typography.Text>
      </Flex>
    </Show>

  </>
}
const inner_style: React.CSSProperties = {
  position: 'absolute',
  border: 0,
  outline: 0,
  width: '100%',
  height: '100%',
  alignContent: 'center',
  padding: 0,
  margin: 0,
}